package com.bjpowernode.dataservice.service.impl;

import com.bjpowernode.api.model.BidInfo;
import com.bjpowernode.api.model.IncomeRecord;
import com.bjpowernode.api.model.ProductInfo;
import com.bjpowernode.api.service.IncomeService;
import com.bjpowernode.api.service.InvestService;
import com.bjpowernode.api.vo.IncomeInfo;
import com.bjpowernode.contacts.YLBConst;
import com.bjpowernode.dataservice.mapper.BidInfoMapper;
import com.bjpowernode.dataservice.mapper.FinanceAccountMapper;
import com.bjpowernode.dataservice.mapper.IncomeRecordMapper;
import com.bjpowernode.dataservice.mapper.ProductInfoMapper;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @description:
 * @author: panDeng_Zhu
 * @time: 2022/11/19 13:13
 */
@DubboService(interfaceClass = IncomeService.class, version = "1.0")
public class IncomeServiceImpl implements IncomeService {

    @Resource
    private IncomeRecordMapper incomeRecordMapper;

    @Resource
    private ProductInfoMapper infoMapper;

    @Resource
    private BidInfoMapper bidInfoMapper;

    @Resource
    private FinanceAccountMapper accountMapper;

    /**
     * 查询用户最近收益记录
     *
     * @param userId
     * @return
     */
    @Override
    public List<IncomeInfo> queryIncomeInfoByUserId(Integer userId, Integer pageNo, Integer pageSize) {
        if (pageNo == null || pageNo < 1) {
            pageNo = 1;
        }
        if (pageSize == null || pageSize < 0) {
            pageSize = 5;
        }
        int offset = (pageNo - 1) * pageSize;
        List<IncomeInfo> incomeInfoList = incomeRecordMapper.selectByUserId(userId, offset, pageSize);
        return incomeInfoList;
    }

    /**
     * 定时任务：生成收益计划
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized void generateIncomePlan() {
        Date curDate = new Date();
        Date beginTime = DateUtils.truncate(DateUtils.addDays(curDate, -1), Calendar.DATE);
        Date endTime = DateUtils.truncate(curDate, Calendar.DATE);

        //1.获取满标产品
        List<ProductInfo> list = infoMapper.selectSelledProduct(beginTime, endTime);

        //2.每个满标产品的投资记录
        //产品类型，周期
        Integer productType = -1, cycle = 0, productId = 0;
        //到期时间，满标时间
        Date expireDate = null, fullDateTime = null;
        //利息，日利率
        BigDecimal income = null, dayRate = null;
        //更新记录的行数
        int rows = 0;

        for (ProductInfo product : list) {
            productId = product.getId();
            productType = product.getProductType();
            fullDateTime = product.getProductFullTime();
            cycle = product.getCycle();
            //日利率
            dayRate = product.getRate().divide(new BigDecimal("360"), 10, RoundingMode.HALF_UP)
                    .divide(new BigDecimal("100"), 10, RoundingMode.HALF_UP);

            List<BidInfo> bidInfoList = bidInfoMapper.selectBiListByProductId(product.getId());

            //计算每笔投资的利息，到期时间
            for (BidInfo bidInfo : bidInfoList) {
                if (productType == YLBConst.PRODUCT_TYPE_XINSHOUBAO) {
                    //新手宝，周期是天
                    //到期时间 = 起息日（满标的第二天）+周期
                    expireDate = DateUtils.addDays(fullDateTime, (1 + cycle));
                    //利息=本金*利率*周期
                    income = bidInfo.getBidMoney().multiply(dayRate).multiply(new BigDecimal(cycle));
                } else {
                    //优选,散标，周期是月（30天）
                    expireDate = DateUtils.addDays(fullDateTime, (1 + (cycle * 30)));
                    //利息=本金*利率*周期
                    income = bidInfo.getBidMoney().multiply(dayRate).multiply(new BigDecimal(cycle * 30));
                }
                //把利息和到期时间，存放到b_income_record
                IncomeRecord incomeRecord = new IncomeRecord();
                incomeRecord.setBidId(bidInfo.getId());
                incomeRecord.setUid(bidInfo.getUid());
                incomeRecord.setBidMoney(bidInfo.getBidMoney());
                incomeRecord.setIncomeDate(expireDate);
                incomeRecord.setIncomeMoney(income);
                incomeRecord.setIncomeStatus(YLBConst.INCOME_STATUS_PLAN);
                incomeRecord.setProdId(productId);
                incomeRecordMapper.insertSelective(incomeRecord);
            }
            //3.在生成收益计划后，更新产品的状态为2
            product.setProductStatus(YLBConst.INVEST_PRODUCT_PLAN);
            rows = infoMapper.updateByPrimaryKeySelective(product);
            if (rows < 1) {
                throw new RuntimeException("生成将收益计划，更新产品状态失败");
            }
        }
    }

    /**
     * 定时任务： 收益返还
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized void generateIncomeBack() {

        int rows = 0;
        //1.获取要处理的到期的收益计划的记录
        List<IncomeRecord> incomeRecordList = incomeRecordMapper.selectExpireIncomePlan();

        //对每个收益计划，返还资金和利息
        for (IncomeRecord incomeRecord : incomeRecordList) {
            //2.更新资金账号
            rows = accountMapper.updateByIncomeBack(incomeRecord.getUid(), incomeRecord.getBidMoney(), incomeRecord.getIncomeMoney());
            if (rows < 1) {
                throw new RuntimeException("收益返还，更新账号资金失败");
            }
            //3.更新收益表状态为1
            incomeRecord.setIncomeStatus(YLBConst.INCOME_STATUS_BACK);
            rows = incomeRecordMapper.updateByPrimaryKeySelective(incomeRecord);
            if (rows<1){
                throw new RuntimeException("收益返还，更新收益表收益记录状态失败");
            }
        }

    }
}
